package model.scaling;

import java.util.ArrayList;
import java.util.List;

import model.auxillary.Parameter;
import model.auxillary.ParameterCollectionScaling;
import model.auxillary.ParameterListScaling.ParameterType;

//#Neu
/**
 * A {@code Location} is part of the scaling. It allows calculations of 
 * relative energy efficiencies of a location.
 * @author Sebastian Perlwitz
 *
 */
public class Location extends Scaling implements ILocation {

	/**
	 * The rank of this {@code Location}. It is used to give parameters a 
	 * unique abbreviation.
	 */
	private int rank;
	
	/**
	 * A List that holds every factory that belongs to this location.
	 */
	private ArrayList<IFactory> factories;
	
	/**
	 * To create a new {@code Location}.
	 * @param name the name of the location.
	 * @param id a unique idea that identifies this location.
	 * @param rank the rank of this location.
	 */
	public Location(
			String name,
			String id,
			int rank) {
		super(name, id);
		this.rank = rank;
		factories = new ArrayList<IFactory>();
		addParameters();
	}
	
	@Override
 	public void addFactory(IFactory factory) {
 		factories.add(factory);
 	}
	
	@Override
	public void removeAllFactoriesOfLocation() {
		factories.clear();
	}
	
	@Override
	public ArrayList<IFactory> getFactories() {
		return factories;
	}
 	
 	/**
	 * To add the locations' defining parameters.
     */
	private void addParameters(){
		List<Parameter> newParams = new ArrayList<Parameter>();
		
		newParams.add(new Parameter(
				"E_CStandort",
				"E_CStandort," + rank,
				"<html>E<sub>C,Standort, " + rank + "</sub></html>",
				"<html>[Wh]</html>",
				false,
				this));
		
		parameters.addScalingParameters(
				ParameterType.INTERIM_RESULT_PARAMETER, newParams);
		newParams.clear();
		
		newParams.add(new Parameter(
				"Relative Energieeffizienz",
				"REE_Standort," + rank,
				"<html>REE<sub>Standort, " + rank + "</sub></html>",
				"<html>[%]</html>",
				false,
				this));
		
		parameters.addScalingParameters(
				ParameterType.LOCATION_RESULT_PARAMETER, newParams);
	}
	
	@Override
	public void calculate() {
		
		error = false;
    	aborted = false;
    	
    	double h = 0.0;
    	double E_CStandort = 0.0;
		
		for(IFactory factory : factories) {
			double E_CWerk = factory.getParameter("E_CWerk", 
					ParameterType.INTERIM_RESULT_PARAMETER).getValue();
			double REE_Werk = factory.getParameter("REE_Werk", 
					ParameterType.FACTORY_RESULT_PARAMETER).getValue();
			
			// Change unit of REE_Werk from [%] to [1].
			REE_Werk /= 100;
			
			h += E_CWerk * REE_Werk;
			E_CStandort += E_CWerk;
		}
		
		double REE_Standort = h / E_CStandort; // [1]
		REE_Standort *= 100; // [%]
		
		getParameter("E_CStandort", 
				ParameterType.INTERIM_RESULT_PARAMETER).setValue(E_CStandort);
		getParameter("REE_Standort", 
				ParameterType.LOCATION_RESULT_PARAMETER).setValue(REE_Standort);
   }

	@Override
	public boolean aborted() {
		return aborted;
	}

	@Override
	public boolean getError() {
		return error;
	}
	
	@Override
	public Parameter getParameter(String abbreviation, ParameterType type) {

		// An example: To find the parameter 'f_lambda,1' by searching for
		// 'f_lambda'.
		String a = abbreviation + "_" + rank;
		String b = abbreviation + "," + rank;
		Parameter paramA = parameters.getParameter(type, a);
		Parameter paramB = parameters.getParameter(type, b);
		if(paramA == null) {
			return paramB;
		} else {
			return paramA;
		}
	}
	
	@Override
	public List<ParameterCollectionScaling> getResults() {
		List<ParameterCollectionScaling> results =
				new ArrayList<ParameterCollectionScaling>();
		results.add(parameters.getParameterCollection(
				ParameterType.LOCATION_RESULT_PARAMETER));
		return results;
	}
	
}
